import ResizeObserver from 'resize-observer-polyfill';

import type { MutableRefObject } from 'react';

type TargetValue<T> = T | undefined | null;
type ObserverCallbackParams = { left: number; top: number; width: number; height: number };

type TargetType = HTMLElement | Element | Window | Document;

export type BasicTarget<T extends TargetType = Element> =
  | (() => TargetValue<T>)
  | TargetValue<T>
  | MutableRefObject<TargetValue<T>>;

//获取元素觉
export function getElementFixPosition(element: any): [number, number, number, number] {
  const pos = element.getBoundingClientRect();
  return [pos.left, pos.top, pos.width, pos.height];
}

//监控元素
export function observerElement(element: any, cb: (params: ObserverCallbackParams) => void) {
  const observer = new ResizeObserver((entries) => {
    entries.forEach((entry) => {
      const [left, top, width, height] = getElementFixPosition(entry.target);
      cb && cb({ left, top, width, height });
    });
  });

  observer.observe(element);

  return observer;
}

export function getTargetElement<T extends TargetType>(target: BasicTarget<T>, defaultElement?: T) {
  if (!target) {
    return defaultElement;
  }

  let targetElement: TargetValue<T>;

  if (typeof target === 'function') {
    targetElement = target();
  } else if ('current' in target) {
    targetElement = target.current;
  } else {
    targetElement = target;
  }

  return targetElement;
}
